﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace GComp.Apps.EasyStock.DataModel {
    public class DataManager {

        #region Constructor and instance

        private DataManager() {
        }

        private static DataManager instance;
        public static DataManager Instance {
            get { return instance ?? (instance = new DataManager()); }
        }

        #endregion //Constructor and instance

        private GroupsList groups = new GroupsList();
        public GroupsList Groups { get { return groups; } private set { groups = value; } }

        public async Task<DataManager> SetUp() {
            return await LoadData();
        }

        public async Task<DataManager> TearDown() {
            await SaveData();
            return this;
        }

        private async Task<DataManager> LoadData() {
            try {
                StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("data.bin");

                // Get an output stream for the SessionState file and write the state asynchronously
                using (Stream fileStream = await file.OpenStreamForReadAsync()) {
                    MemoryStream sessionData = new MemoryStream();
                    await fileStream.CopyToAsync(sessionData);
                    Debug.WriteLine("Size: " + sessionData.Length);
                    sessionData.Seek(0, SeekOrigin.Begin);

                    DataContractSerializer serializer = new DataContractSerializer(typeof(GroupsList));
                    GroupsList list = serializer.ReadObject(sessionData) as GroupsList;

                    if (list != null) {
                        groups = list;
                    }
                }
            } catch (Exception) {
                //or better? FileNotFoundException
                StockGroup group1 = new StockGroup {
                    Name = "Common",
                    Description = "Important companies in the IT. "
                };
                Groups.Add(group1);
                group1.Entries.Add(new StockEntry {
                    Name = "Microsoft",
                    Symbol = "MSFT"
                });
                group1.Entries.Add(new StockEntry {
                    Name = "Apple",
                    Symbol = "AAPL"
                });
                group1.Entries.Add(new StockEntry {
                    Name = "Google",
                    Symbol = "GOOG"
                });
                group1.Entries.Add(new StockEntry {
                    Name = "Facebook",
                    Symbol = "FB"
                });
            }
            return this;
        }

        private async Task<DataManager> SaveData() {
            MemoryStream sessionData = new MemoryStream();
            DataContractSerializer serializer = new DataContractSerializer(typeof(GroupsList));
            serializer.WriteObject(sessionData, Groups);
            Debug.WriteLine("Size: " + sessionData.Length);

            try {
                // Get an output stream for the SessionState file and write the state asynchronously
                StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("data.bin", CreationCollisionOption.ReplaceExisting);
                using (Stream fileStream = await file.OpenStreamForWriteAsync()) {
                    sessionData.Seek(0, SeekOrigin.Begin);
                    await sessionData.CopyToAsync(fileStream);
                    await fileStream.FlushAsync();
                    Debug.WriteLine("Position: " + fileStream.Position);
                }
                Debug.WriteLine("ready");
            } catch (Exception e) {
                Debug.WriteLine("failure: " + e.Message);
            }
            return this;
        }
    }

    public class GroupsList : List<StockGroup> {
        public StockGroup this[string uniquId] {
            get { return this.FirstOrDefault(group => group.Id == uniquId); }
        }
    }
}
